package reflect;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;

public class Test2 {
    public static void main(String[] args) throws URISyntaxException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
        //类所在目录
        File dir = new File(Test2.class.getResource(".").toURI());
        //检查路径
        System.out.println(dir);
        //确定与类在同一个包的类数量
        //通过过滤器获取.class后缀的文件名
        File[] subs=dir.listFiles(f->f.getName().endsWith(".class"));
        //遍历类对象
        for (File sub:subs) {
        //检查文件名
            System.out.println(sub.getName());
            //通过文件名获取到类名，去掉.class后缀
            String className=sub.getName().substring(0,sub.getName().indexOf("."));
            //获取Test2.class.getPackage().getName()包名，拼接出类对象
            Class cls=Class.forName(
                    Test2.class.getPackage().getName()+"."+className);
            //通过类对象实例化
            Object o = cls.newInstance();/*InstantiationException属于没有无参构造器异常*/
            //获取每个类的除超类以外的方法
            Method[] methods= cls.getDeclaredMethods();
            //遍历类对象的方法
            for (Method m:methods) {
                //检查类的方法名
                System.out.println(m.getName());
                //判断方法是否存在参数以及方法名是否包含"e"
                if (m.getParameterCount()==0&&m.getName().contains("s")){/*有参执行会报错IllegalArgumentException*/
                    //检查符合条件的方法名
                    System.out.println(m.getName());
                    //暴力反射，强行开启私有方法的权限
                    m.setAccessible(true);
                    //执行方法
                    m.invoke(o);
                    //关闭暴力反射
                    m.setAccessible(false);
                }
            }
        }
    }
}
